package com.ktkj.init.service.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.ktkj.init.constant.CharConstant;
import com.ktkj.init.constant.DictConstant;
import com.ktkj.init.dto.DictImportForm;
import com.ktkj.init.entity.Dict;
import com.ktkj.init.service.DictService;
import com.ktkj.init.utils.DateUtils;
import com.ktkj.init.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Slf4j
public class DictDataListener extends AnalysisEventListener<DictImportForm> {

    private DictService dictService;

    public DictDataListener(DictService dictService) {
        this.dictService = dictService;
    }

    /**
     * 批量插入数据-限制为每次10条，以便达到性能最优，实际使用视情况而定
     */
    private static final int BATCH_COUNT = 10;
    List<Dict> parentList = new ArrayList<>();
    List<Dict> childrenList = new ArrayList<>();
    List<String> descsList = new ArrayList<>();
    int sumCount = 0;
    int errorCount = 0;
    StringBuilder errorMsg = new StringBuilder();

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        String[] headValues = {"描述", "类型", "节点类型", "级别", "父字典", "创建时间"};
        for (int i = 0; i < headValues.length; i++) {
            String headValue = headValues[i];
            String value = headMap.get(i);
            if (!headValue.equals(value)) {
                throw new ExcelAnalysisException("excel文件表头错误！");
            }
        }
    }

    @Override
    public void invoke(DictImportForm data, AnalysisContext context) {
        //log.info("解析到一条数据:{}", JSON.toJSONString(data));
        sumCount++;
        //获取行号
        ReadRowHolder readRowHolder = context.readRowHolder();
        Integer rowIndex = readRowHolder.getRowIndex();

        //1、必填项：{描述、类型、节点类型}
        //2、唯一项：{描述}
        if (StringUtils.isNotBlank(data.getDescs()) && StringUtils.isNotBlank(data.getType()) && StringUtils.isNotBlank(data.getManageType())) {
            if (!descsList.contains(data.getDescs())) {
                descsList.add(data.getDescs());
                Dict dict = dictService.getByDescs(data.getDescs());
                if (dict == null) {
                    Dict bean = new Dict();
                    SpringUtils.copyPropertiesIgnoreNull(data, bean);
                    String[] manageTypeArr = data.getManageType().split("-");
                    bean.setManageType(manageTypeArr[0]);
                    bean.setCreateDate(DateUtils.parseDate(data.getCreateDate()));
                    if (StringUtils.isNotBlank(bean.getParentDescs())) {
                        childrenList.add(bean);
                    } else {
                        bean.setParentId(DictConstant.HIGHEST_CODE);
                        parentList.add(bean);
                    }
                } else {
                    errorCount++;
                    errorMsg.append("第").append(rowIndex).append("行|与数据库重复").append(CharConstant.CR_LF);
                }
            } else {
                errorCount++;
                errorMsg.append("第").append(rowIndex).append("行|与本批次数据重复").append(CharConstant.CR_LF);
            }
            /*if (list.size() >= BATCH_COUNT) {
                saveData();
                list.clear();
            }*/
        } else {
            errorCount++;
            errorMsg.append("第").append(rowIndex).append("行|必填项为空").append(CharConstant.CR_LF);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //log.info("所有数据解析完成！");
        saveData();
        if (StringUtils.isNotBlank(errorMsg.toString())) {
            StringBuilder resultMsg = new StringBuilder();
            resultMsg.append("总条数：").append(sumCount).append(CharConstant.CR_LF);
            resultMsg.append("成功条数：").append(sumCount - errorCount).append(CharConstant.CR_LF);
            resultMsg.append("失败条数：").append(errorCount).append(CharConstant.CR_LF);
            resultMsg.append("失败原因：").append(CharConstant.CR_LF).append(errorMsg);
            throw new ExcelAnalysisException(resultMsg.toString());
        }
    }

    /**
     * 批量插入数据
     */
    private void saveData() {
        //log.info("{}条数据，开始存储数据库！", list.size());
        if (!CollectionUtils.isEmpty(parentList)) {
            dictService.saveBatch(parentList, BATCH_COUNT);
            log.info("parentList存储数据库成功！");
        }
        if (!CollectionUtils.isEmpty(childrenList)) {
            for (Dict bean : childrenList) {
                Dict dict = dictService.getByDescs(bean.getParentDescs());
                bean.setParentId(dict != null ? dict.getId() : null);
            }
            dictService.saveBatch(childrenList, BATCH_COUNT);
            log.info("childrenList存储数据库成功！");
        }

    }
}

